home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / src.arc / KSUBR.C < prev    next >
C/C++ Source or Header  |  1989-08-19  |  6KB  |  217 lines

  1. #include <stdio.h>    /***/
  2. /* Machine or compiler-dependent portions of kernel - Turbo-C version */
  3. #include <dos.h>
  4. #include "global.h"
  5. #include "proc.h"
  6. #include "pc.h"
  7. #include "commands.h"
  8.  
  9. extern int16 Intstk[];
  10. static oldNull;
  11.  
  12. /* Template for contents of jmp_buf in Turbo C */
  13. struct env {
  14.     unsigned    sp;
  15.     unsigned    ss;
  16.     unsigned    flag;
  17.     unsigned    cs;
  18.     unsigned    ip;
  19.     unsigned    bp;
  20.     unsigned    di;
  21.     unsigned    es;
  22.     unsigned    si;
  23.     unsigned    ds;
  24. };
  25.  
  26. static int chkintstk __ARGS((void));
  27. static int stkutil __ARGS((struct proc *pp));
  28.  
  29. void
  30. kinit()
  31. {
  32.     int i;
  33.  
  34.     /* Initialize interrupt stack for high-water-mark checking */
  35.     for(i=0;i<512;i++)
  36.         Intstk[i] = STACKPAT;
  37.  
  38.     /* Remember location 0 pattern to detect null pointer derefs */
  39.     oldNull = *(unsigned short *)NULL;
  40.  
  41. }
  42. /* Print process table info
  43.  * Since things can change while ps is running, the ready proceses are
  44.  * displayed last. This is because an interrupt can make a process ready,
  45.  * but a ready process won't spontaneously become unready. Therefore a
  46.  * process that changes during ps may show up twice, but this is better
  47.  * than not having it showing up at all.
  48.  */
  49. int
  50. ps(argc,argv,p)
  51. int argc;
  52. char *argv[];
  53. void *p;
  54. {
  55.     register struct proc *pp;
  56.     register struct env *ep;
  57.     int i;
  58.  
  59.     printf("Stack %x max intstk %u\n",getss(),chkintstk());
  60.  
  61.     printf("PID       SP        stksize   maxstk    event     flags     name\n");
  62.  
  63.     for(pp = Susptab;pp != NULLPROC;pp = pp->next){
  64.         ep = (struct env *)&pp->env;
  65.         printf("%-10lx%-10lx%-10u%-10u%-10lx%c%c%c       %s\n",
  66.          ptol(pp),
  67.          ptol(MK_FP(ep->ss,ep->sp)),
  68.          pp->stksize,
  69.          stkutil(pp),
  70.          ptol(pp->event),
  71.          pp->i_state ? 'I' : ' ',
  72.          (pp->state & WAITING) ? 'W' : ' ',
  73.          (pp->state & SUSPEND) ? 'S' : ' ',
  74.          pp->name);
  75.     }
  76.     for(i=0;i<PHASH;i++){
  77.         for(pp = Waittab[i];pp != NULLPROC;pp = pp->next){
  78.             ep = (struct env *)&pp->env;
  79.             printf("%-10lx%-10lx%-10u%-10u%-10lx%c%c%c       %s\n",
  80.              ptol(pp),ptol(MK_FP(ep->ss,ep->sp)),pp->stksize,stkutil(pp),
  81.              ptol(pp->event),
  82.              pp->i_state ? 'I' : ' ',
  83.              (pp->state & WAITING) ? 'W' : ' ',
  84.              (pp->state & SUSPEND) ? 'S' : ' ',
  85.              pp->name);
  86.         }
  87.     }
  88.     for(pp = Rdytab;pp != NULLPROC;pp = pp->next){
  89.         ep = (struct env *)&pp->env;
  90.         printf("%-10lx%-10lx%-10u%-10u          %c%c%c       %s\n",
  91.          ptol(pp),ptol(MK_FP(ep->ss,ep->sp)),pp->stksize,stkutil(pp),
  92.          pp->i_state ? 'I' : ' ',
  93.          (pp->state & WAITING) ? 'W' : ' ',
  94.          (pp->state & SUSPEND) ? 'S' : ' ',
  95.          pp->name);
  96.     }
  97.     if(Curproc != NULLPROC){
  98.         ep = (struct env *)&Curproc->env;
  99.         printf("%-10lx%-10lx%-10u%-10u          %c         %s\n",
  100.          ptol(Curproc),ptol(MK_FP(ep->ss,ep->sp)),Curproc->stksize,
  101.          stkutil(Curproc),
  102.          Curproc->i_state ? 'I' : ' ',
  103.          Curproc->name);
  104.     }
  105.     return 0;
  106. }
  107. static int
  108. stkutil(pp)
  109. struct proc *pp;
  110. {
  111.     unsigned i;
  112.     register int16 *sp;
  113.  
  114.     i = pp->stksize;
  115.     for(sp = pp->stack;*sp == STACKPAT && sp < pp->stack + pp->stksize;sp++)
  116.         i--;
  117.     return i;
  118. }
  119. /* Return number of used words in interrupt stack. Note hardwired value
  120.  * for stack size; this is also found in the various .asm files
  121.  */
  122. static int
  123. chkintstk()
  124. {
  125.     register int i;
  126.     register int16 *cp;
  127.  
  128.     for(i=512,cp = Intstk; i != 0 && *cp == STACKPAT; cp++)
  129.         i--;
  130.     return i;
  131. }
  132.  
  133. /* Verify that stack pointer for current process is within legal limits;
  134.  * also check that no one has dereferenced a null pointer
  135.  */
  136. void
  137. chkstk()
  138. {
  139.     int16 *sbase;
  140.     int16 *stop;
  141.     int16 *sp;
  142.  
  143.     sp = MK_FP(_SS,_SP);
  144.     if(_SS == _DS){
  145.         /* Probably in interrupt context */
  146.         return;
  147.     }
  148.     sbase = Curproc->stack;
  149.     stop = sbase + Curproc->stksize;
  150.     if(sp < sbase || sp >= stop){
  151.         printf("Stack violation, process %s\n",Curproc->name);
  152.         printf("SP = %lx, legal stack range [%lx,%lx)\n",
  153.         ptol(sp),ptol(sbase),ptol(stop));
  154.         fflush(stdout);
  155.         killself();
  156.     }
  157.     if(*(unsigned short *)NULL != oldNull){
  158.         printf("WARNING: Location 0 smashed, process %s\n",Curproc->name);
  159.         *(unsigned short *)NULL = oldNull;
  160.         fflush(stdout);
  161.     }
  162. }
  163. /* Machine-dependent initialization of a task */
  164. void
  165. psetup(pp,iarg,parg1,parg2,pc)
  166. struct proc *pp;    /* Pointer to task structure */
  167. int iarg;        /* Generic integer arg */
  168. void *parg1;        /* Generic pointer arg #1 */
  169. void *parg2;        /* Generic pointer arg #2 */
  170. void (*pc)();        /* Initial execution address */
  171. {
  172.     register int *stktop;
  173.     register struct env *ep;
  174.  
  175.     /* Set up stack to make it appear as if the user's function was called
  176.      * by killself() with the specified arguments. When the user returns,
  177.      * killself() automatically cleans up.
  178.      *
  179.      * First, push args on stack in reverse order, simulating what C
  180.      * does just before it calls a function.
  181.      */
  182.     stktop = (int *)(pp->stack + pp->stksize);
  183. #ifdef    LARGEDATA
  184.     *--stktop = FP_SEG(parg2);
  185. #endif
  186.     *--stktop = FP_OFF(parg2);
  187. #ifdef    LARGEDATA
  188.     *--stktop = FP_SEG(parg1);
  189. #endif
  190.     *--stktop = FP_OFF(parg1);
  191.     *--stktop = iarg;
  192.         
  193.     /* Now push the entry address of killself(), simulating the call to
  194.      * the user function.
  195.      */
  196. #ifdef    LARGECODE
  197.     *--stktop = FP_SEG(killself);
  198. #endif
  199.     *--stktop = FP_OFF(killself);
  200.  
  201.     /* Set up task environment. Note that for Turbo-C, the setjmp
  202.      * sets the interrupt enable flag in the environment so that
  203.      * interrupts will be enabled when the task runs for the first time.
  204.      * Note that this requires newproc() to be called with interrupts
  205.      * enabled!
  206.      */
  207.     setjmp(pp->env);
  208.     ep = (struct env *)&pp->env;
  209.     ep->ss = FP_SEG(stktop);
  210.     ep->sp = FP_OFF(stktop);
  211.     ep->cs = FP_SEG(pc);    /* Doesn't hurt in small model */
  212.     ep->ip = FP_OFF(pc);
  213.     /* Task initially runs with interrupts on */
  214.     pp->i_state = 1;
  215. }
  216.  
  217.